﻿using System;
using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Windows.Forms;
using System.Data;
using System.Data.Common;
using System.Drawing;
using System.Reflection;
using THSLib;
using THSERP.BusinessEntities;
namespace THSERP.BaseProvider
{
    public partial class THSLookupEdit : DevExpress.XtraEditors.LookUpEdit
    {
        #region variables
        protected THSERPScreen _screen;
        protected String _THSFieldGroup;
        protected String _THSFieldParent;
        protected String _THSFieldRelation;
        protected String _THSDataSource;
        protected String _THSDataMember;
        protected bool _THSAllowDummy;
        protected String _THSSelectType;
        protected String _THSSelectTypeValue;
        protected String _THSError;
        protected String _currentDisplayText = String.Empty;
        protected DataTable dtLookupTable;
        protected String _THSPropertyName;
        protected String _THSComment;
        protected String _THSPrivilege;
        protected SortedList _valueTypes;
        #endregion

        #region Public properties
        public THSERPScreen Screen
        {
            get
            {
                return _screen;
            }
            set
            {
                _screen = value;
            }
        }
        
        [Category("THS")]
        public String THSFieldGroup
        {
            get
            {
                return _THSFieldGroup;
            }
            set
            {
                _THSFieldGroup = value;
            }
        }

        [Category("THS")]
        public String THSFieldParent
        {
            get
            {
                return _THSFieldParent;
            }
            set
            {
                _THSFieldParent = value;
            }
        }

        [Category("THS")]
        public String THSFieldRelation
        {
            get
            {
                return _THSFieldRelation;
            }
            set
            {
                _THSFieldRelation = value;
            }
        }

        [Category("THS")]
        public String THSDataSource
        {
            get
            {
                return _THSDataSource;
            }
            set
            {
                _THSDataSource = value;
            }
        }

        [Category("THS")]
        public String THSDataMember
        {
            get
            {
                return _THSDataMember;
            }
            set
            {
                _THSDataMember = value;
            }
        }

        [Category("THS")]
        public bool THSAllowDummy
        {
            get
            {
                return _THSAllowDummy;
            }
            set
            {
                _THSAllowDummy = value;
            }
        }

        [Category("THS")]
        public String THSSelectType
        {
            get
            {
                return _THSSelectType;
            }
            set
            {
                _THSSelectType = value;
            }
        }

        [Category("THS")]
        public String THSSelectTypeValue
        {
            get
            {
                return _THSSelectTypeValue;
            }
            set
            {
                _THSSelectTypeValue = value;
            }
        }

        public String CurrentDisplayText
        {
            get
            {
                return _currentDisplayText;
            }
            set
            {
                _currentDisplayText = value;
            }
        }
        public SortedList ValueTypes
        {
            get { return _valueTypes; }
            set { _valueTypes = value; }
        }
        [Category("THS")]
        public String THSError
        {
            get 
            {
                return _THSError;
            }
            set
            {
                _THSError = value;
            }
        }

        [Category("THS")]
        public String THSPropertyName
        {
            get
            {
                return _THSPropertyName;
            }
            set
            {
                _THSPropertyName = value;
            }
        }

        [Category("THS")]
        public String THSComment
        {
            get
            {
                return _THSComment;
            }
            set
            {
                _THSComment = value;
            }
        }

        [Category("THS")]
        public String THSPrivilege
        {
            get
            {
                return _THSPrivilege;
            }
            set
            {
                _THSPrivilege = value;
            }
        }
        #endregion

        public THSLookupEdit()
        {
            InitializeComponent();
        }

        public THSLookupEdit(IContainer container)
        {
            container.Add(this);

            InitializeComponent();
        }

        public THSLookupEdit(THSERPScreen scr)
        {
            _screen = new THSERPScreen();
            _screen = scr;

            InitializeComponent();

            InitializeControl();
        }

        #region Initialize LookupEdit functions
        public void InitializeControl()
        {
            try
            {
                if (!String.IsNullOrEmpty(THSSelectTypeValue))
                {
                    _valueTypes = new SortedList();
                    String[] values = THSSelectTypeValue.Split(new char[] { ';' });
                    foreach (String value in values)
                    {
                        _valueTypes.Add(value, value);
                    }
                }
                InitObjectDataToLookupEdit();
                if (!String.IsNullOrEmpty(THSDataSource) && !String.IsNullOrEmpty(THSDataMember))
                {
                    if (!THSDataSource.Equals("ADConfigValues"))
                        Screen.BindingDataControl(this);
                }
                this.Properties.ShowPopupShadow = true;
                this.Properties.SearchMode = DevExpress.XtraEditors.Controls.SearchMode.AutoFilter;
               // this.Properties.PopupResizeMode = true;
                

                //this.Properties.ShowDropDown = DevExpress.XtraEditors.Controls.ShowDropDown.SingleClick;
                this.Click += ((BaseModuleERP)Screen.Module).Control_Click;
                this.DoubleClick += new EventHandler(THSLookupEdit_DoubleClick);
                this.KeyUp += new KeyEventHandler(((BaseModuleERP)Screen.Module).Control_KeyUp);
                
                this.EditValueChanged += new EventHandler(THSLookupEdit_EditValueChanged);
                this.TextChanged += new EventHandler(THSLookupEdit_TextChanged);
                this.Validated += new EventHandler(THSLookupEdit_Validated);
                this.KeyDown += new KeyEventHandler(THSLookupEdit_KeyDown);

                
                if (THSDbUtil.IsForeignKey(THSDataSource, THSDataMember))
                    this.QueryPopUp += new CancelEventHandler(THSLookupEdit_QueryPopUp);

                
                else if(!String.IsNullOrEmpty(this.THSFieldParent))
                    this.QueryPopUp += new CancelEventHandler(THSLookupEdit_QueryPopUp);

                
                else
                {
                    String configValueGroup = GetConfigValueGroup();
                    if (!String.IsNullOrEmpty(configValueGroup))
                        this.QueryPopUp += new CancelEventHandler(THSLookupEdit_QueryPopUp);
                }
            }
            catch (Exception)
            {
                MessageBox.Show("Init LookupEdit", "THS Bug");
            }
        }

        void THSLookupEdit_TextChanged(object sender, EventArgs e)
        {
            CurrentDisplayText = this.Text;

        }

        void THSLookupEdit_DoubleClick(object sender, EventArgs e)
        {
            this.SelectAll();
        }

        protected virtual void InitObjectDataToLookupEdit()
        {
            String strTableName = THSDataSource;
            String strColumnName = THSDataMember;
           

            //If DataMember is not empty
            if (!String.IsNullOrEmpty(strColumnName))
            {
                //If is foreign key
                if (THSDbUtil.IsForeignKey(strTableName, strColumnName))
                {
                    String strLookupTable = THSDbUtil.GetPrimaryTableWhichForeignColumnReferenceTo(THSDataSource, THSDataMember);
                    if (!InitObjectDataFromLookupTable(strLookupTable))
                    {
                        MessageBox.Show(String.Format("Define lookup table {0}", strLookupTable), "THS Bug");
                    }
                }
                else
                {
                    //If LookupEdit get data from ADConfigValues and not binding to Object
                    if (THSDataSource.Equals("ADConfigValues"))
                    {
                        this.Properties.DataSource = ADConfigValueUtility.glbdsConfigValues.Tables[THSDataMember];
                        this.Properties.ValueMember = "Value";
                        this.Properties.DisplayMember = "Text";
                        DevExpress.XtraEditors.Controls.LookUpColumnInfo column = new DevExpress.XtraEditors.Controls.LookUpColumnInfo();
                        column.FieldName = "Text";
                        column.Width = 100;
                        this.Properties.Columns.Add(column);
                        this.Properties.PopupWidth = column.Width;
                    }
                    else
                    {
                        String strConfigValueTable = GetConfigValueGroup();
                        if (ADConfigValueUtility.glbdsConfigValues.Tables[strConfigValueTable] != null)
                        {
                            this.Properties.DataSource = ADConfigValueUtility.glbdsConfigValues.Tables[strConfigValueTable];
                            this.Properties.ValueMember = "Value";
                            this.Properties.DisplayMember = "Text";
                            DevExpress.XtraEditors.Controls.LookUpColumnInfo column = new DevExpress.XtraEditors.Controls.LookUpColumnInfo();
                            column.Caption = "Name";
                            column.FieldName = "Text";
                            column.Width = 100;
                            this.Properties.Columns.Add(column);
                            this.Properties.PopupWidth = column.Width;
                        }
                        else
                        {
                            if (!InitObjectDataFromLookupTable(strTableName))
                            {
                                MessageBox.Show(String.Format("Define lookup table {0}", strTableName), "THS Bug");
                            }
                        }

                    }

                }
            }
            else
            {
                if (!String.IsNullOrEmpty(strTableName))
                {
                    if (!InitObjectDataFromLookupTable(strTableName))
                    {
                        MessageBox.Show(String.Format("Define lookup table {0}", strTableName), "THS Bug");
                    }
                }
            }
        }

        /// <summary>
        /// Init object data from lookup table
        /// </summary>
        /// 
        public bool InitObjectDataFromLookupTable(String strLookupTable)
        {
            
            //InitLookupEditColumns();

            this.Properties.DisplayMember = this.Properties.DisplayMember;
            this.Properties.ValueMember = this.Properties.ValueMember;
            THSApp.InitDataToLookupTable(strLookupTable);
            if (THSApp.LookupTables[strLookupTable] != null)
            {
                dtLookupTable = ((DataSet)THSApp.LookupTables[strLookupTable]).Tables[0].Copy();
                if (THSAllowDummy)
                {
                    if (dtLookupTable.Rows.Count > 0)
                    {
                        if (this.Properties.ValueMember != null)
                        {
                            if (Convert.ToInt32(dtLookupTable.Rows[0][this.Properties.ValueMember]) > 0)
                            {
                                DataRow row = dtLookupTable.NewRow();

                                row[this.Properties.DisplayMember] = String.Empty;
                                row[this.Properties.ValueMember] = 0;
                                dtLookupTable.Rows.InsertAt(row, 0);
                            }
                        }
                    }
                }

                this.Properties.DataSource = dtLookupTable;

                if (((DataSet)THSApp.LookupTables[strLookupTable]).Tables[0].Rows.Count > 0)
                    this.ItemIndex = 0;
                return true;
            }
            return false;
        }

        private void InitLookupEditColumns()
        {
            //Init Columns for lookup Edit
            STFieldsInfo objSTFieldsInfo = new STFieldsController().GetFieldBySTModuleIDAndSTUserGroupIDAndSTFieldName(
                                                            ((BaseModuleERP)Screen.Module).ModuleID, THSApp.CurrentUserGroupInfo.ADUserGroupID,
                                                            this.Name);
            STFieldColumnsController objSTFieldColumnsController = new STFieldColumnsController();
            DataSet dsFieldColumns = objSTFieldColumnsController.GetAllDataByForeignColumn("STFieldID", objSTFieldsInfo.STFieldID);
            if (dsFieldColumns.Tables.Count > 0)
            {
                this.Properties.PopupWidth = 0;
                foreach (DataRow rowFieldColumn in dsFieldColumns.Tables[0].Rows)
                {
                    STFieldColumnsInfo objSTFieldColumnsInfo = (STFieldColumnsInfo)objSTFieldColumnsController.GetObjectFromDataRow(rowFieldColumn);
                    if (objSTFieldColumnsInfo != null)
                    {
                        DevExpress.XtraEditors.Controls.LookUpColumnInfo column = new DevExpress.XtraEditors.Controls.LookUpColumnInfo();
                        column.Caption = objSTFieldColumnsInfo.STFieldColumnCaption;
                        column.FieldName = objSTFieldColumnsInfo.STFieldColumnFieldName;
                        column.FormatType = (DevExpress.Utils.FormatType)Enum.Parse(typeof(DevExpress.Utils.FormatType), objSTFieldColumnsInfo.STFieldColumnFormatType);
                        column.FormatString = objSTFieldColumnsInfo.STFieldColumnFormatString;
                        column.Width = objSTFieldColumnsInfo.STFieldColumnWidth;
                        this.Properties.Columns.Add(column);
                        this.Properties.PopupWidth += column.Width;
                    }
                }
            }
            dsFieldColumns.Dispose();
        }

        
        private void InvalidateDataSourceToLookupEditWhichBelongsToFieldParent()
        {
           
            THSLookupEdit lkeFieldParent = (THSLookupEdit)this.Screen.Module.Controls[THSFieldParent];

            if (lkeFieldParent != null)
            {
                String strFieldParentLookupTable = THSDbUtil.GetPrimaryTableWhichForeignColumnReferenceTo(lkeFieldParent.THSDataSource, lkeFieldParent.THSDataMember);
                String strFieldParentPrimaryColumn = THSDbUtil.GetTablePrimaryColumn(strFieldParentLookupTable);
                String strLookupTable = THSDbUtil.GetPrimaryTableWhichForeignColumnReferenceTo(this.THSDataSource, this.THSDataMember);
               
                
                if(String.IsNullOrEmpty(strLookupTable))
                    strLookupTable = this.THSDataSource;

                String strForeignColumn = "FK_" + strFieldParentPrimaryColumn;
                BaseBusinessController objLookupTableController = BusinessControllerFactory.GetBusinessController(strLookupTable + "Controller");

                if (objLookupTableController != null)
                {
                    DataSet ds = objLookupTableController.GetAllDataByForeignColumn(strForeignColumn, lkeFieldParent.EditValue);
                    //Binding LookupEdit
                    if (ds.Tables.Count > 0)
                    {
                        dtLookupTable = ds.Tables[0];
                        
                        if (!String.IsNullOrEmpty(THSSelectType))
                        {
                            if (THSDbUtil.ColumnIsExist(strLookupTable, THSSelectType))
                                for (int i = 0; i < dtLookupTable.Rows.Count; i++)
                                {
                                    DataRow row = dtLookupTable.Rows[i];
                                    String value = row[THSSelectType].ToString();
                                    if (ValueTypes[value] == null)
                                    {
                                        dtLookupTable.Rows.Remove(row);
                                        i--;
                                    }
                                }
                        }

                        if (THSAllowDummy)
                        {
                            if (dtLookupTable.Rows.Count > 0)
                            {
                                if (Convert.ToInt32(dtLookupTable.Rows[0][this.Properties.ValueMember]) > 0)
                                {
                                    DataRow row = dtLookupTable.NewRow();
                                    row[this.Properties.DisplayMember] = String.Empty;
                                    row[this.Properties.ValueMember] = 0;
                                    dtLookupTable.Rows.InsertAt(row, 0);
                                }
                            }
                        }
                    }
                    BindingSource bds = new BindingSource();
                    bds.DataSource = dtLookupTable;
                    this.Properties.DataSource = bds;

                    
                    CurrentDisplayText = String.Empty;
                }
            }
        }

        
        private void InvalidateDataSourceToLookupEdit()
        {
           
            String strLookupTable = THSDbUtil.GetPrimaryTableWhichForeignColumnReferenceTo(THSDataSource, THSDataMember);
            DateTime dtLastCreatedDate = THSDbUtil.GetLastCreatedDateOfTable(strLookupTable);
            DateTime dtLastUpdatedDate = THSDbUtil.GetLastUpdatedDateOfTable(strLookupTable);

            if (dtLastCreatedDate.CompareTo(((DateTime)THSApp.LookupTablesUpdatedDate[strLookupTable])) > 0 ||
                dtLastUpdatedDate.CompareTo(((DateTime)THSApp.LookupTablesUpdatedDate[strLookupTable])) > 0)
            {
                //Refesh Data Source
                BaseBusinessController objLookupTableController = BusinessControllerFactory.GetBusinessController(strLookupTable + "Controller");
                if (objLookupTableController != null)
                {
                    DataSet ds = objLookupTableController.GetAllObjects();
                    if (ds.Tables.Count > 0)
                    {
                        // Update Last Updated Date of Lookup Table
                        THSApp.LookupTablesUpdatedDate[strLookupTable] = DateTime.Now;
                        ((DataSet)THSApp.LookupTables[strLookupTable]).Tables.Clear();
                        ((DataSet)THSApp.LookupTables[strLookupTable]).Tables.Add(ds.Tables[0].Copy());
                    }

                    
                    CurrentDisplayText = String.Empty;
                }
            }

            dtLookupTable = ((DataSet)THSApp.LookupTables[strLookupTable]).Tables[0].Copy();

            if (!String.IsNullOrEmpty(THSSelectType))
            {
                if (THSDbUtil.ColumnIsExist(strLookupTable, THSSelectType))
                    for (int i = 0; i < dtLookupTable.Rows.Count; i++)
                    {
                        DataRow row = dtLookupTable.Rows[i];
                        String value = row[THSSelectType].ToString();
                        if (ValueTypes[value]==null)
                        {
                            dtLookupTable.Rows.Remove(row);
                            i--;
                        }
                    }
            }
            if (THSAllowDummy)
            {
                if (dtLookupTable.Rows.Count > 0)
                {
                    if (Convert.ToInt32(dtLookupTable.Rows[0][this.Properties.ValueMember]) > 0)
                    {
                        DataRow row = dtLookupTable.NewRow();

                        row[this.Properties.DisplayMember] = String.Empty;
                        row[this.Properties.ValueMember] = 0;
                        dtLookupTable.Rows.InsertAt(row, 0);
                    }
                }
            }
            this.Properties.DataSource = dtLookupTable;
        }

        #region Event Handlers
        private void THSLookupEdit_QueryPopUp(object sender, CancelEventArgs e)
        {
            
            String configValueGroup = GetConfigValueGroup();
            if (!String.IsNullOrEmpty(configValueGroup))
                this.Properties.DataSource = ADConfigValueUtility.glbdsConfigValues.Tables[configValueGroup];
            else
            {
                if (!String.IsNullOrEmpty(THSFieldParent))
                    InvalidateDataSourceToLookupEditWhichBelongsToFieldParent();
                else
                    InvalidateDataSourceToLookupEdit();
            }
        }

        
        protected virtual void THSLookupEdit_EditValueChanged(object sender, EventArgs e)
        {
               //CurrentDisplayText = this.Text;
        }

        protected virtual void THSLookupEdit_KeyDown(object sender, KeyEventArgs e)
        {
                CurrentDisplayText = this.Text;
        }

        protected virtual void THSLookupEdit_Validated(object sender, EventArgs e)
        {
            String strDisplayMember = this.Properties.DisplayMember;
            if (!String.IsNullOrEmpty(strDisplayMember) && !String.IsNullOrEmpty(CurrentDisplayText))
            {
                if (this.Properties.DataSource != null)
                {
                    try
                    {
                        DataTable dtb = new DataTable();
                        if (this.Properties.DataSource.GetType() == typeof(DataTable))
                            dtb = ((DataTable)this.Properties.DataSource);
                        else
                            if (this.Properties.DataSource.GetType() == typeof(BindingSource))
                            {
                                BindingSource bds = (BindingSource)this.Properties.DataSource;
                                if (bds.DataSource.GetType() == typeof(DataSet))
                                    dtb = ((DataSet)bds.DataSource).Tables[0];
                                else
                                    if (bds.DataSource.GetType() == typeof(DataTable))
                                        dtb = (DataTable)bds.DataSource;
                            }

                        if (dtb.Columns[strDisplayMember] != null)
                        {

                            String strFilter = String.Empty;
                            if (dtb.Columns[strDisplayMember].DataType == typeof(String) || dtb.Columns[strDisplayMember].DataType == typeof(DateTime))
                                strFilter = String.Format("[{0}]='{1}'", strDisplayMember, CurrentDisplayText);
                            else
                                strFilter = String.Format("[{0}]= {1}", strDisplayMember, CurrentDisplayText);
                            DataRow[] arrRows = dtb.Select(strFilter);
                            if (arrRows.Length > 0)
                                return;
                            //hieu.nguyen remove 02/08/2011
                            //if (this.Properties.Columns[strDisplayMember] != null)
                            //    MessageBox.Show(String.Format("{0} {1} không tồn tại.", this.Properties.Columns[strDisplayMember].Caption, CurrentDisplayText), "#Cảnh báo#", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            //else
                            //    MessageBox.Show(String.Format("{0} {1} không tồn tại.", dtb.Columns[strDisplayMember].ColumnName, CurrentDisplayText), "#Cảnh báo#", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            CurrentDisplayText = String.Empty;
                            this.Focus();
                            this.EditValue = 0;
                        }
                    }
                    catch (Exception)
                    {
                        return;
                    }
                }
            }
        }
        #endregion

        
        public static THSLookupEdit Instance(String strInstanceName, String strModuleName)
        {
            if (!String.IsNullOrEmpty(strInstanceName))
            {
                Type gridType = THSApp.THSERPAssembly.GetType("THSERP.Modules." + strModuleName + "." + strInstanceName + "LookupEdit");
                if (gridType != null)
                {
                    return (THSLookupEdit)gridType.InvokeMember("", BindingFlags.CreateInstance, null, null, null);
                }
                else
                {
                    gridType = THSApp.THSERPAssembly.GetType("THSERP." + strInstanceName + "GridControl");
                    if (gridType != null)
                        return (THSLookupEdit)gridType.InvokeMember("", BindingFlags.CreateInstance, null, null, null);
                    else
                        return new THSLookupEdit();
                }
            }
            else
                return new THSLookupEdit();
        }

        /// <summary>
        /// Get ConfigValueGroup
        /// </summary>
        /// 

        public String GetConfigValueGroup()
        {
            if (THSDataSource.Equals("ADConfigValues"))
            {
                return THSDataMember;
            }
            else
            {
                String strConfigValueTable = String.Empty;
                if (THSDataMember.Contains("Combo"))
                    strConfigValueTable = THSDataMember.Substring(2, THSDataMember.Length - 7);
                else
                    strConfigValueTable = THSDataMember.Substring(2, THSDataMember.Length - 2);

                
                if (strConfigValueTable.Contains("AddressStateProvince"))
                    strConfigValueTable = "AddressStateProvince";
                else if (strConfigValueTable.Contains("AddressPostalCode"))
                    strConfigValueTable = "AddressPostalCode";

                if (ADConfigValueUtility.glbdsConfigValues.Tables[strConfigValueTable] != null)
                {
                    if (this.Tag.ToString() == "SC" || this.THSAllowDummy)
                        strConfigValueTable = strConfigValueTable + "Search";
                    return strConfigValueTable;
                }
            }
            return String.Empty;
        }
        #endregion
    }
}
